package com.now.presum;

/**
 * 303. 区域和检索 - 数组不可变 给定一个整数数组nums，处理以下类型的多个查询:
 * <p>
 * 计算索引 left 和 right （包含 left 和 right）之间的 nums 元素的 和 ，其中 left <= right 实现 NumArray 类：
 * <p>
 * NumArray(int[] nums) 使用数组 nums 初始化对象 int sumRange(int i, int j) 返回数组 nums 中索引 left 和 right 之间的元素的
 * 总和 ，包含 left 和 right 两点（也就是 nums[left] + nums[left + 1] + ... + nums[right] )
 */
public class NumArray {

  /**
   * 前缀和数组,用于记录原数组下标前面的元素总和
   */
  int[] preSum;

  public NumArray(int[] nums) {
    preSum = new int[nums.length + 1];
    for (int i = 1; i <= nums.length; i++) {
      preSum[i] = preSum[i - 1] + nums[i - 1];
    }
  }

  /**
   * 将快速、频繁地计算⼀个索引区间内的元素之和，用减法做替代,效率更好，时间复杂度低
   *
   * @param left
   * @param right
   * @return
   */
  public int sumRange(int left, int right) {
    return preSum[right + 1] - preSum[left];
  }

  public static void main(String[] args) {
    int[] nums = {-2, 0, 3, -5, 2, -1};
    NumArray numArray = new NumArray(nums);
    System.out.println(numArray.sumRange(0, 2));
    System.out.println(numArray.sumRange(2, 5));
    System.out.println(numArray.sumRange(0, 5));
  }

  /**
   * 普通方法，多次调用了sumRange进行循环求和，效率差
   */
//  int[] numArray;
//  public NumArray(int[] nums) {
//    numArray = nums;
//  }
//
//  public int sumRange(int left, int right) {
//    int sum = 0;
//    for(int i=left;i<=right;i++){
//      sum += numArray[i];
//    }
//    return sum;
//  }

}
